
**********************************************************************
* REPLICATION FILE FOR "UNCOVERING THE SOURCE OF PATRIMONIAL VOTING" *
*                    AHLSKOG AND BRÄNNSTRÖM                          *
**********************************************************************

/*

A few notes for understanding the code
1. LopNr is the variable used to identify individuals across different register sources.
	Each individual has a unique but anonymized identifier. This replaces the so-called
	"personnummer", or personal number, the Swedish version of a social secutity number
	that is comprised of an individuals birth date plus four additional digits.
2. LopNrParID is the shared twin pair identifier.
3. Zygosity is determined by the STR variable BESTZYG, which is coded as 1 for identical twins,
	and 2 for same-sex fraternal twins. In the code below, we create a new variable called
	zyg that has the same function.

*/

clear all
local root = "D:"
cd "D:\replication files"


* This function is used later to prepare the R-file for ACE analysis
capture program drop cotwin
program define cotwin

	qui: gen `1'2=.
	qui: sort LopNrParID TwinNr
	qui: by LopNrParID: replace `1'2=`1'[2] if TwinNr==1
	qui: by LopNrParID: replace `1'2=`1'[1] if TwinNr==2
	qui: rename `1' `1'1

end


* This function merges a specified variable from a specified dataset
capture program drop getdata
program define getdata

	* Save existing as temp and load new
	qui: save temp, replace
	qui: use `1'
	qui: keep LopNr `2'
	
	* Drop duplicates
	qui: gen n=.
	qui: bysort LopNr: replace n=[_n]
	qui: keep if n==1
	qui: drop n
	
	* Merge in old
	qui: merge 1:1 LopNr using temp, nogen
	qui: keep if LopNrParID!=.

end



* Start log file
log using logfile.txt, replace




*****************
* SETUP DATASET *
*****************

* Cohort file and twin pair identifiers from the Swedish Twin Registry
use "`root'\STR\cohort.dta"
merge 1:1 LopNr using "`root'\STR\parid.dta", nogen

* Keep only actual twin pairs
bysort LopNrParID: gen n=[_N]
keep if n==2
drop n
label variable LopNrParID "Twin pair ID"

* Other adjustments
replace SEX=SEX-1
rename SEX Sex
label variable Sex "Sex of twin"
gen BirthYear=substr(Byear,1,4)
destring BirthYear, replace
label variable BirthYear "Birth year of twin pair"
drop Byear
label variable LopNr "Identifier"

* Zygosity
gen Relatedness=.
replace Relatedness=0.5 if BESTZYG==2
replace Relatedness=1 if BESTZYG==1
drop BESTZYG
label variable Relatedness "Coefficient of relatedness in twin pair"
keep if Relatedness!=.
gen zyg=3-(2*Relatedness)
	
* Number in twinpair
sort LopNrParID LopNr
by LopNrParID: gen TwinNr=[_n]
label variable TwinNr "Twin nr (first used)"




********************
* WEALTH VARIABLES *
********************

* Get wealth variables from registers
foreach i in 1999 2000 2001 2002 2003 2004 2005 2006 2007 {
	getdata `root'\Formog\Formogenhet`i'.dta FREALMV
	rename FREALMV real_assets`i'
	getdata `root'\Formog\Formogenhet`i'.dta  FSUMMV
	rename FSUMMV assets`i'
	getdata `root'\Formog\Formogenhet`i'.dta  FFINMV
	rename FFINMV fin_assets`i'
}

* Generate average wealth variables and winsorize
gen wealth=(assets1999+assets2000+assets2001+ assets2002 ///
	+assets2003+assets2004+assets2005+assets2006+assets2007)/9000000
winsor2 wealth, cuts(0 99) trim replace
gen finwealth=(fin_assets1999+fin_assets2000+fin_assets2001+ fin_assets2002 ///
	+fin_assets2003+fin_assets2004+fin_assets2005+fin_assets2006+fin_assets2007)/9000000
winsor2 finwealth, cuts(0 99) trim replace
gen realwealth=(real_assets1999+real_assets2000+real_assets2001+real_assets2002 ///
	+real_assets2003+real_assets2004+real_assets2005+real_assets2006+real_assets2007)/9000000
winsor2 realwealth, cuts(0 99) trim replace
	
* Hyperbolic sine transformations
gen hs_wealth = ln((wealth)+sqrt((wealth)^2 +1))
label variable hs_wealth "H/S wealth"
gen hs_finwealth=ln((finwealth)+sqrt((finwealth)^2 +1))
label variable hs_finwealth "H/S financial wealth"
gen hs_realwealth=ln((realwealth)+sqrt((realwealth)^2 +1))
label variable hs_realwealth "H/S real wealth"

* Delta wealth
gen delta_wealth=(assets2007-assets1999)/1000000
gen delta_finwealth=(fin_assets2007-fin_assets1999)/1000000
gen delta_realwealth=(real_assets2007-real_assets1999)/1000000

* Cleanup
drop real_assets* assets* fin_assets*





*****************
* ATTITUDE DATA *
*****************

* Get all issue preferences from STR SALTY
getdata `root'\STRSalty\slty_map.dta ATTITYD33_1
rename ATTITYD33_1 decrease_public_sector
replace decrease_public_sector=. if decrease_public_sector==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_2
rename ATTITYD33_2 decrease_defense_spending
replace decrease_defense_spending=. if decrease_defense_spending==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_3
rename ATTITYD33_3 decrease_welfare
replace decrease_welfare=. if decrease_welfare==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_4
rename ATTITYD33_4 lower_taxes
replace lower_taxes=. if lower_taxes==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_5
rename ATTITYD33_5 property_tax
replace property_tax=. if property_tax==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_6
rename ATTITYD33_6 sell_public_enterprise
replace sell_public_enterprise=. if sell_public_enterprise==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_7
rename ATTITYD33_7 decrease_economic_inequality
replace decrease_economic_inequality=. if decrease_economic_inequality==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_8
rename ATTITYD33_8 more_private_healthcare
replace more_private_healthcare=. if more_private_healthcare==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_9
rename ATTITYD33_9 decrease_finmarket_impact
replace decrease_finmarket_impact=. if decrease_finmarket_impact==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_10
rename ATTITYD33_10 keep_maxtaxa
replace keep_maxtaxa=. if keep_maxtaxa==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_11
rename ATTITYD33_11 more_freeschools
replace more_freeschools=. if more_freeschools==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_12
rename ATTITYD33_12 earlier_grades
replace earlier_grades=. if earlier_grades==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_13
rename ATTITYD33_13 more_support_countryside
replace more_support_countryside=. if more_support_countryside==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_14
rename ATTITYD33_14 six_hour_workday
replace six_hour_workday=. if six_hour_workday==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_15
rename ATTITYD33_15 ban_pornography
replace ban_pornography=. if ban_pornography==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_16
rename ATTITYD33_16 limit_abortion
replace limit_abortion=. if limit_abortion==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_17
rename ATTITYD33_17 harder_punishment
replace harder_punishment=. if harder_punishment==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_18
rename ATTITYD33_18 better_animal_protection
replace better_animal_protection=. if better_animal_protection==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_19
rename ATTITYD33_19 no_nuclear_power
replace no_nuclear_power=. if no_nuclear_power==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_20
rename ATTITYD33_20 no_cars_in_cities
replace no_cars_in_cities=. if no_cars_in_cities==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_21
rename ATTITYD33_21 decrease_pollution
replace decrease_pollution=. if decrease_pollution==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_22
rename ATTITYD33_2 less_carbondioxide
replace less_carbondioxide=. if less_carbondioxide==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_23
rename ATTITYD33_23 more_skilled_immigration
replace more_skilled_immigration=. if more_skilled_immigration==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_24
rename ATTITYD33_24 language_test_citizenship
replace language_test_citizenship=. if language_test_citizenship==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_25
rename ATTITYD33_25 decrease_aid
replace decrease_aid=. if decrease_aid==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_26
rename ATTITYD33_26 fewer_refugees
replace fewer_refugees=. if fewer_refugees==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_27
rename ATTITYD33_27 more_support_immigrant_culture
replace more_support_immigrant_culture=. if more_support_immigrant_culture==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_28
rename ATTITYD33_28 abolish_debt
replace abolish_debt=. if abolish_debt==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_29
rename ATTITYD33_29 more_freedom_companies
replace more_freedom_companies=. if more_freedom_companies==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_30
rename ATTITYD33_30 leave_eu
replace leave_eu=. if leave_eu==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_31
rename ATTITYD33_31 instate_euro
replace instate_euro=. if instate_euro==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_32
rename ATTITYD33_32 join_nato
replace join_nato=. if join_nato==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_33
rename ATTITYD33_3 more_free_trade
replace more_free_trade=. if more_free_trade==9
getdata `root'\STRSalty\slty_map.dta ATTITYD33_34
rename ATTITYD33_34 support_war_on_terror
replace support_war_on_terror=. if support_war_on_terror==9


* Free-market dimension
gen free_market = lower_taxes + sell_public_enterprise ///
	- decrease_finmarket_impact + more_freedom_companies
su free_market
replace free_market = (free_market-r(min))/(r(max)-r(min))

* Redistribution dimension
gen redistribution = decrease_public_sector + decrease_welfare - decrease_economic_inequality ///
	+ more_private_healthcare - keep_maxtaxa + more_freeschools
replace redistribution = 0-redistribution
su redistribution
replace redistribution = (redistribution-r(min))/(r(max)-r(min))

* Property taxes
su property_tax
replace property_tax=(property_tax-r(min))/(r(max)-r(min))

* Left-right dimension
getdata `root'\STRSalty\slty_map.dta ATTITYD25
rename ATTITYD25 leftright
replace leftright=. if leftright==99
su leftright
replace leftright = (leftright-r(min))/(r(max)-r(min))

* Party choice dimension
getdata `root'\STRSalty\slty_map.dta ATTITYD26
rename ATTITYD26 political_party
gen party=.
replace party=0 if political_party==1
replace party=1 if political_party==2
replace party=2 if political_party==7
replace party=3 if political_party==3
replace party=4 if political_party==4
replace party=5 if political_party==6
replace party=6 if political_party==5
replace party=7 if political_party==8
su party
replace party= (party-r(min))/(r(max)-r(min))





*************
 * CONTROLS *
 ************
 
 * Income variables
foreach i in 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 {
	getdata `root'\LISA\LISA`i'.dta ForvErs
	rename ForvErs income_`i'
}

gen income=(income_2000+income_2001+income_2002+income_2003+income_2004+income_2005 ///
	+income_2006+income_2007+income_2008+income_2009)/100
gen raw_income=income
winsor2 income, cuts(0 99) trim replace
su income
replace income=(income-r(min))/(r(max)-r(min))
drop income_*


* Education
getdata "`root'\LISA\LISA2009" Sun2000niva
gen education_years=.
replace education_years=7 if Sun2000niva<200
replace education_years=9 if inrange(Sun2000niva,200,299)
replace education_years=9.5 if Sun2000niva==204
replace education_years=10 if inrange(Sun2000niva,310,319)
replace education_years=11 if inrange(Sun2000niva,320,329)
replace education_years=12 if inrange(Sun2000niva,330,339)
replace education_years=13 if inrange(Sun2000niva,410,419)
replace education_years=14 if inrange(Sun2000niva,520,529)
replace education_years=15 if inrange(Sun2000niva,530,539)
replace education_years=16 if inrange(Sun2000niva,540,549)
replace education_years=17 if inrange(Sun2000niva,550,559)
replace education_years=18 if inrange(Sun2000niva,600,629)
replace education_years=19 if inrange(Sun2000niva,640,649)
drop Sun2000niva



* Number of non-adult children
getdata "`root'\LISA\LISA2010.dta" Barn0_3
getdata "`root'\LISA\LISA2010.dta" Barn4_6
getdata "`root'\LISA\LISA2010.dta" Barn7_10
getdata "`root'\LISA\LISA2010.dta" Barn11_15
getdata "`root'\LISA\LISA2010.dta" Barn16_17
gen children=Barn0_3+Barn4_6+Barn7_10+Barn11_15+Barn16_17


* Occupation category
getdata "`root'\LISA\LISA2009" SSYK3
replace SSYK3="" if SSYK3=="***"
destring SSYK3, replace
gen occupation=floor(SSYK3/10)
drop SSYK3




* Label all variables
label variable wealth "Wealth, MKr"
label variable finwealth "Financial wealth, MKr"
label variable finwealth "Share financial wealth"
label variable realwealth "Real wealth, MKr"
label variable delta_wealth "$\Delta$ wealth"

label variable income "Work income"
label variable education_years "Education years"
label variable children "Children under 18"
label variable occupation "Occupation"

label variable free_market "Free market preferences"
label variable redistribution "Redistributive preferences"
label variable leftright "Left-right orientation"
label variable party "Party choice (L-R)"
label variable property_tax "Property tax support"




* Make dataset for the second part of the analysis (ACE models in R)
* A few variables also need rescaling for the models to converge
preserve
keep wealth finwealth realwealth hs_wealth redistribution free_market leftright party property_tax zyg LopNrParID TwinNr
replace wealth=wealth*25
replace finwealth=finwealth*25
replace realwealth=realwealth*25
replace hs_wealth=hs_wealth*100
replace free_market=free_market*100
replace redistribution=redistribution*100
replace leftright=leftright*100
replace party=party*100
replace property_tax=property_tax*100

cotwin wealth
cotwin finwealth
cotwin realwealth

cotwin redistribution
cotwin free_market
cotwin leftright
cotwin party
cotwin property_tax

drop LopNrParID
save dataset_r.dta, replace
restore







****************
* MAIN RESULTS *
****************



* All main models, with standard specification of wealth as well as hyperbolic sines
foreach v in free_market property_tax redistribution leftright party {

	* Models
	
	local controls = "Sex income education_years i.children"
	
	* Match correct wealth type to outcome
	if "`v'"=="free_market"|"`v'"=="leftright"|"`v'"=="party" {
		local indep = "wealth"
	}
	if "`v'"=="redistribution" {
		local indep = "finwealth"
	}
	if "`v'"=="property_tax" {
		local indep = "realwealth"
	}
	
	* Go through both standard and hyperbolic sine
	foreach i in "" "hs_" {
	
		* Label for table
		local varlabel : variable label `v'

		* Run models, output tables
		reg `v' `i'`indep' if zyg==1, cluster(LopNrParID)
		outreg2 using "table_`i'`v'.tex", replace title("`varlabel'") ctitle("Naive") label tex(frag) keep(`i'`indep') addtext(Controls, No, Occupation FE, No) nocons
		reg `v' `i'`indep' `controls' if zyg==1, cluster(LopNrParID)
		outreg2 using "table_`i'`v'.tex", append title("`varlabel'") ctitle("Naive") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, No) nocons
		reg `v' `i'`indep' `controls' i.occupation if zyg==1, cluster(LopNrParID)
		outreg2 using "table_`i'`v'.tex", append title("`varlabel'") ctitle("Naive") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, Yes) nocons
		reg `v' `i'`indep' `controls' if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
		outreg2 using "table_`i'`v'.tex", append title("`varlabel'") ctitle("Within") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, No) nocons
		reg `v' `i'`indep' `controls' i.occupation if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
		outreg2 using "table_`i'`v'.tex", append title("`varlabel'") ctitle("Within") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, Yes) nocons
		reg `v' `i'`indep' `controls' i.occupation delta_wealth if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
		outreg2 using "table_`i'`v'.tex", append title("`varlabel'") ctitle("Within") label tex(frag)  keep(`i'`indep' delta_wealth) addtext(Controls, Yes, Occupation FE, Yes) nocons

	}
}








********************
* APPENDIX RESULTS *
********************



* Create twin contact rate
save temp, replace
use "`root'\STRSalt\salt_twinc.dta", clear
destring KONTAKT_ANTAL_GANG_PER_VECKA_V, force replace
destring KONTAKT_ANTAL_GANG_PER_MANAD_V, force replace
destring KONTAKT_ANTAL_GANG_AR_V, force replace
gen kontakt_per_ar=.
replace kontakt_per_ar=KONTAKT_ANTAL_GANG_PER_VECKA_V*52 if KONTAKT_ANTAL_GANG_PER_VECKA_V!=.
replace kontakt_per_ar=KONTAKT_ANTAL_GANG_PER_MANAD_V*12 if KONTAKT_ANTAL_GANG_PER_MANAD_V!=.
replace kontakt_per_ar=KONTAKT_ANTAL_GANG_AR_V if KONTAKT_ANTAL_GANG_AR_V!=.
replace kontakt_per_ar=0 if KONTAKT_HOW_OFTEN_ALDRIG==5
keep LopNr kontakt_per_ar
merge 1:1 LopNr using temp, nogen
save temp, replace

* Test contact interactions
sort LopNrParID TwinNr
foreach v in wealth finwealth realwealth ///
	income education_years free_market property_tax redistribution leftright party children {
	
	bysort LopNrParID: gen d_`v' = `v'[1]-`v'[2]
	replace d_`v'=. if TwinNr==2
}

* Define contact rate as the pair-average self-reported rate
bysort LopNrParID: egen m_kontakt = mean(kontakt_per_ar)
label variable m_kontakt "Contact rate"

* Free-market preferences
reg d_free_market c.d_wealth##c.m_kontakt c.d_wealth##c.d_education_years c.m_kontakt#c.d_education_years ///
	c.d_wealth##c.d_income c.m_kontakt#c.d_income ///
	c.d_wealth##c.d_children c.m_kontakt#c.d_children if zyg==1 & TwinNr==1
	
* Left-right orientation
reg d_leftright c.d_wealth##c.m_kontakt c.d_wealth##c.d_education_years c.m_kontakt#c.d_education_years ///
	c.d_wealth##c.d_income c.m_kontakt#c.d_income ///
	c.d_wealth##c.d_children c.m_kontakt#c.d_children if zyg==1 & TwinNr==1

* Party
reg d_party c.d_wealth##c.m_kontakt c.d_wealth##c.d_education_years c.m_kontakt#c.d_education_years ///
	c.d_wealth##c.d_income c.m_kontakt#c.d_income ///
	c.d_wealth##c.d_children c.m_kontakt#c.d_children if zyg==1 & TwinNr==1
	
* Redistributive preferences
reg d_redistribution c.d_finwealth##c.m_kontakt c.d_finwealth##c.d_education_years c.m_kontakt#c.d_education_years ///
	c.d_finwealth##c.d_income c.m_kontakt#c.d_income ///
	c.d_finwealth##c.d_children c.m_kontakt#c.d_children if zyg==1 & TwinNr==1
	
* Property taxes
reg d_property_tax c.d_realwealth##c.m_kontakt c.d_realwealth##c.d_education_years c.m_kontakt#c.d_education_years ///
	c.d_realwealth##c.d_income c.m_kontakt#c.d_income ///
	c.d_realwealth##c.d_children c.m_kontakt#c.d_children if zyg==1 & TwinNr==1

	
	

* Use first five PC's from Oskarsson et al
gen dimension1 = decrease_public_sector + lower_taxes + sell_public_enterprise + more_private_healthcare + more_freeschools + more_freedom_companies
gen dimension2 = more_support_countryside + six_hour_workday
gen dimension3 = harder_punishment - more_skilled_immigration + language_test_citizenship + decrease_aid + fewer_refugees - more_support_immigrant_culture 
gen dimension4 = decrease_pollution + less_carbondioxide
gen dimension5 = leave_eu - instate_euro - join_nato
forvalues i=1(1)5 {
	label variable dimension`i' "Dimension `i'"
}

foreach v in dimension1 dimension2 dimension3 dimension4 dimension5 {
	su `v'
	replace `v' = (`v'-r(min))/(r(max)-r(min))
}

foreach v in dimension1 dimension2 dimension3 dimension4 dimension5 {

	* Models
	local varlabel : variable label `v'
	local controls = "Sex income education_years i.children"
	local indep = "wealth"
	
	foreach i in "" "hs_" {

		* Run models, output tables
		reg `v' `i'`indep' if zyg==1, cluster(LopNrParID)
		outreg2 using "appendix_table_`i'`v'.tex", replace title("`varlabel'") ctitle("Naive") label tex(frag) keep(`i'`indep') addtext(Controls, No, Occupation FE, No) nocons
		reg `v' `i'`indep' `controls' i.occupation if zyg==1, cluster(LopNrParID)
		outreg2 using "appendix_table_`i'`v'.tex", append title("`varlabel'") ctitle("Naive") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, Yes) nocons
		reg `v' `i'`indep' `controls' i.occupation if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
		outreg2 using "appendix_table_`i'`v'.tex", append title("`varlabel'") ctitle("Within") label tex(frag)  keep(`i'`indep') addtext(Controls, Yes, Occupation FE, Yes) nocons
	}
}




* Additional test of H1
reg free_market finwealth if zyg==1, cluster(LopNrParID)
reg free_market finwealth Sex income education_years i.children if zyg==1, cluster(LopNrParID)
reg free_market finwealth Sex income education_years i.children i.occupation if zyg==1, cluster(LopNrParID)
reg free_market finwealth income education_years i.children if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
reg free_market finwealth income education_years i.children i.occupation if zyg==1, cluster(LopNrParID) absorb(LopNrParID)
reg free_market finwealth income education_years i.children i.occupation delta_wealth if zyg==1, cluster(LopNrParID) absorb(LopNrParID)



* Population comparison
gen avg_income=raw_income*1000
winsor2 avg_income, cuts(0 99) trim
su avg_income_tr BirthYear education_years Sex if leftright!=. & zyg==1
su avg_income_tr BirthYear education_years Sex if leftright!=. & zyg==1 & Sex==0
su avg_income_tr BirthYear education_years Sex if leftright!=. & zyg==1 & Sex==1






* Cleanup
erase temp.dta
log close _all
